package com.czk.classreader.method.addcode;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/8/16 16:55
 */
public class MethodEnterVisitor extends ClassVisitor {
    public MethodEnterVisitor(int api, ClassVisitor classVisitor) {
        super(api, classVisitor);
    }

    @Override
    public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
        MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions);
        // 添加自己的代码
        // 排除构造方法，因为构造方法第一行应该是super()，可能会导致出错
        if (methodVisitor!=null&&!"<init>".equals(name)){
            methodVisitor=new MethodEnterAdapter(api,methodVisitor);
        }
        return methodVisitor;
    }
    public static class MethodEnterAdapter extends MethodVisitor {
        public MethodEnterAdapter(int api, MethodVisitor methodVisitor ) {
            super(api, methodVisitor);
        }

        @Override
        public void visitCode() {
            // 首先，处理自己的代码逻辑
            // 使用super，就会避免NullPointerException异常的情况。因为使用super的情况下，就是调用父类定义的方法，在本例中其实就是调用MethodVisitor类里定义的方法。
            // 在MethodVisitor类里的visitXxx()方法中，会先对mv进行是否为null的判断，所以就不会出现NullPointerException的情况
            super.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
            super.visitLdcInsn("Method Enter...");
            super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
            // 其次，调用父类的方法实现
            super.visitCode();
        }
    }
}
